package com.wh.base.sys.role.controller;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wh.base.aop.documented.OperLog;
import com.wh.base.sys.menu.service.MenuService;
import com.wh.base.sys.role.controller.form.AccreditForm;
import com.wh.base.sys.role.controller.form.IdForm;
import com.wh.base.sys.role.controller.form.IdsForm;
import com.wh.base.sys.role.controller.form.InsertForm;
import com.wh.base.sys.role.controller.form.SearchListForm;
import com.wh.base.sys.role.controller.form.SearchPageForm;
import com.wh.base.sys.role.controller.form.UpdateForm;
import com.wh.base.sys.role.entity.Role;
import com.wh.base.sys.role.service.RoleService;
import com.wh.base.sys.roleMenu.entity.RoleMenu;
import com.wh.base.sys.roleMenu.service.RoleMenuService;
import com.wh.base.sys.user.service.UserService;
import com.wh.base.sys.userRole.entity.UserRole;
import com.wh.base.sys.userRole.service.UserRoleService;
import com.wh.base.util.R;
import com.wh.base.util.RedisUtil;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.ApiOperation;

/**
 * <p>
 * 系统角色 前端控制器
 * </p>
 *
 * @author WangHong
 * @since 2022-04-20
 */
@Controller
@RequestMapping("/sys/role")
public class RoleController {

	@Autowired
	private RoleService service;

	@Autowired
	private UserService userService;
	
	@Autowired
	private RoleMenuService roleMenuService;
	
	@Autowired
	private UserRoleService userRoleService;
	
	@Autowired
	private MenuService menuService;
	
	@Resource
    private RedisUtil redisUtil;

	@GetMapping("/index")
	@ApiOperation(value = "首页页面")
	@SaCheckPermission("role:view")
	public String index(Model model){
		model.addAttribute("authSign", (Map<String,String>)redisUtil.get("auth_sign_"+StpUtil.getLoginIdAsLong())); //用户权限
		return "role/index";
	}

	@GetMapping("/recycleIndex")
	@ApiOperation(value = "回收站页面")
	@SaCheckPermission("role:recycle")
	public String recycleIndex(Model model){
		model.addAttribute("authSign", (Map<String,String>)redisUtil.get("auth_sign_"+StpUtil.getLoginIdAsLong())); //用户权限
		return "role/recycle";
	}

	@PostMapping("/getPage")
	@ApiOperation(value = "分页查询数据")
	@ResponseBody
	@SaCheckLogin
	public R getPage(@Validated SearchPageForm form){
		Page roadPage = new Page<>(form.getPageNum(), form.getPageSize());
		LambdaQueryWrapper<Role> queryWrapper = new QueryWrapper<Role>().lambda();
		queryWrapper.eq(Role::getDeleteFlag, "0");
		queryWrapper.ne(Role::getId, 1L);
		if(form.getName() != null) {
			queryWrapper.like(Role::getName, form.getName());
		}
		Page pageList = service.page(roadPage, queryWrapper);
		return R.ok().put("page", pageList);
	}

	@PostMapping("/getList")
	@ApiOperation(value = "查询所有数据")
	@ResponseBody
	@SaCheckLogin
	public R getList(@Validated SearchListForm form){
		LambdaQueryWrapper<Role> queryWrapper = new QueryWrapper<Role>().lambda();
		queryWrapper.eq(Role::getDeleteFlag, "0");
		if(form.getName() != null) {
			queryWrapper.like(Role::getName, form.getName());
		}
		return R.ok().put("list", service.list(queryWrapper));
	}

	@PostMapping("/getRecyclePage")
	@ApiOperation(value = "分页查询回收站数据")
	@ResponseBody
	@SaCheckPermission("role:recycle")
	public R getRecyclePage(@Validated SearchPageForm form){
		Page roadPage = new Page<>(form.getPageNum(), form.getPageSize());
		LambdaQueryWrapper<Role> queryWrapper = new QueryWrapper<Role>().lambda();
		queryWrapper.eq(Role::getDeleteFlag, "1");
		if(form.getName() != null) {
			queryWrapper.like(Role::getName, form.getName());
		}
		Page pageList = service.page(roadPage, queryWrapper);
		return R.ok().put("page", pageList);
	}

	@PostMapping("/getById")
	@ApiOperation(value = "根据id查询数据")
	@SaCheckPermission("role:view")
	@ResponseBody
	public R getById(@Validated IdForm form){
		return R.ok().put("obj", service.getById(form.getId()));
	}

	@PostMapping("/add")
	@ApiOperation(value = "添加数据")
	@SaCheckPermission("role:add")
	@ResponseBody
	@OperLog(operModul = "角色管理", operType = "新增" ,operDesc = "新增角色")
	public R add(@Validated InsertForm form){
		Role role = JSONUtil.parse(form).toBean(Role.class);
		role.setCreateTime(new Date());
		role.setCreateUser(userService.getUser().getUsername());
		if(service.save(role)){
			return R.ok("添加成功");
		}else{
			return R.error("添加失败");
		}

	}

	@PostMapping("/update")
	@ApiOperation(value = "修改数据")
	@SaCheckPermission("role:update")
	@ResponseBody
	@OperLog(operModul = "角色管理", operType = "修改" ,operDesc = "修改角色")
	public R update(@Validated UpdateForm form){
		Role role = JSONUtil.parse(form).toBean(Role.class);
		role.setUpdateTime(new Date());
		role.setUpdateUser(userService.getUser().getUsername());
		service.saveOrUpdate(role);
		return R.ok("修改成功");
	}

	@PostMapping("/restore")
	@ApiOperation(value = "根据ids批量还原回收站的数据")
	@SaCheckPermission("role:recycle")
	@ResponseBody
	@OperLog(operModul = "角色管理", operType = "还原角色" ,operDesc = "还原回收站角色")
	public R restore(@Validated IdsForm form){
		List<Long> idList = form.idList();
		if(idList.size() > 0) {
			List<Role> roleList = new ArrayList<>();
			for(Long id : idList) {
				Role role = new Role();
				role.setId(id);
				role.setDeleteFlag("0");
				role.setUpdateTime(new Date());
				role.setUpdateUser(userService.getUser().getUsername());
				roleList.add(role);
			}
			if(roleList.size() > 0) {
				service.saveOrUpdateBatch(roleList);
			}
		}
		return R.ok("还原成功");
	}

	@PostMapping("/recycle")
	@ApiOperation(value = "根据id集合将数据放入回收站")
	@SaCheckPermission("role:recycle")
	@ResponseBody
	@OperLog(operModul = "角色管理", operType = "放入回收站" ,operDesc = "将角色放入回收站")
	public R recycle(@Validated IdsForm form){
		List<Long> idList = form.idList();
		if(idList.size() > 0) {
			List<Role> roleList = new ArrayList<>();
			for(Long id : idList) {
				if(id == 1L) {
					return R.error("超级管理员不允许删除");
				}
				Role role = new Role();
				role.setId(id);
				role.setDeleteFlag("1");
				role.setUpdateTime(new Date());
				role.setUpdateUser(userService.getUser().getUsername());
				roleList.add(role);
			}
			if(roleList.size() > 0) {
				service.saveOrUpdateBatch(roleList);
			}
		}
		return R.ok("删除成功");
	}

	/**
	 * 删除角色, 同步删除角色与权限对应关系, 用户与角色的对应关系
	 * @param form
	 * @return
	 */
	@PostMapping("/delete")
	@ApiOperation(value = "根据id集合彻底删除数据")
	@SaCheckPermission("role:delete")
	@ResponseBody
	@OperLog(operModul = "角色管理", operType = "彻底删除" ,operDesc = "彻底删除角色")
	public R delete(@Validated IdsForm form){
		List<Long> idList = form.idList();
		for(Long id : idList) {
			if(id == 1L) {
				return R.error("超级管理员不允许删除");
			}
		}
		if(idList.size() > 0) {
			service.removeByIds(idList);
			QueryWrapper<RoleMenu> rmWrapper = null;
			QueryWrapper<UserRole> urWrapper = null;
			for(Long id : idList) {
				// 删除菜单对应关系
				rmWrapper = new QueryWrapper<RoleMenu>();
				rmWrapper.eq("role_id", id);
				roleMenuService.remove(rmWrapper);
				
				// 删除用户对应关系
				urWrapper = new QueryWrapper<UserRole>();
				urWrapper.eq("role_id", id);
				userRoleService.remove(urWrapper);
				
			}
		}
		return R.ok("删除成功");
	}
	
	/**
	 * 获取所有菜单, 并与角色已有菜单组合
	 * @param form
	 * @return
	 */
	@PostMapping("/authMenuTree")
	@ApiOperation(value = "角色授权菜单")
	@SaCheckPermission("role:accredit")
	@ResponseBody
	public R authMenuTree(@Validated IdForm form){
		return R.ok().put("data", menuService.getMenuTreeByRoleId(form.getId()));
	}
	
	/**
	 * 删除角色, 同步删除角色与权限对应关系
	 * @param form
	 * @return
	 */
	@PostMapping("/accredit")
	@ApiOperation(value = "为角色授权")
	@SaCheckPermission("role:accredit")
	@ResponseBody
	@OperLog(operModul = "角色管理", operType = "角色授权" ,operDesc = "给角色授权")
	public R accredit(@Validated AccreditForm form){
		//删除已有授权
		QueryWrapper<RoleMenu> queryWrapper = new QueryWrapper<RoleMenu>();
		queryWrapper.eq("role_id", form.getId());
		roleMenuService.remove(queryWrapper);
		//重新保存授权
		List<Long> menuIdList = form.menuIdList();
		if(menuIdList != null && menuIdList.size() >0) {
			RoleMenu rm = null;
			List<RoleMenu> rmList = new ArrayList<>();
			for(Long menuId : menuIdList) {
				rm = new RoleMenu();
				rm.setRoleId(form.getId());
				rm.setMenuId(menuId);
				rmList.add(rm);
			}
			roleMenuService.saveBatch(rmList);
		}
		return R.ok("授权成功");
	}
}
